Docker Cheatsheet

Concept / Command Explanation
Docker Engine Core software that manages images and containers; provides
the Docker daemon, CLI client, and APIs.
Dockerfile A text file containing instructions for building a Docker
image. It specifies base images, layers, commands, etc.
This is a recipe for creating an image.
Docker Image A read-only template built from a Dockerfile. Images contain
all dependencies your application needs. They are immutable,
versioned, and layered.
Docker Container A running instance of an image. Containers are isolated
processes that run on the host OS using the image’s
filesystem. They’re ephemeral by design.
Difference: Dockerfile vs. Image vs. Container • Dockerfile: A set of instructions (recipe) for building an image.
• Image: A static snapshot (read-only) resulting from the Dockerfile build.
• Container: A running (or stopped) instance of an image, isolated but using the host OS kernel.
docker build Builds a Docker image from a Dockerfile. Example:
docker build -t myapp:1.0 .
docker run Creates and runs a container from a specified image. Common
flags: -d (detached), -p (port mapping), --name (container
name). Example:
docker run -d -p 80:80 --name web myapp:1.0
docker stop / start Stops or restarts a running container.
docker stop <container>
docker start <container>
docker ps Lists running containers (use -a to see all).
docker ps -a
docker exec Runs a command within an existing container, often used to
get a shell. Example:
docker exec -it <container> bash
docker logs Shows a container’s logs (use -f for “follow”).
docker logs -f <container>
docker rm Removes one or more containers. You must stop them first.
docker rm <container>
docker rmi Removes one or more images.
docker rmi <image>
docker pull / push Pulls or pushes an image to a remote registry (e.g., Docker
Hub). You need to be logged in to push.
docker pull <image>
docker push <repository>/<image>
docker tag Assigns a new name/tag to an image.
docker tag <source_image> <repo>:<tag>
docker compose Tool for defining and running multi-container Docker apps via
a YAML file (docker-compose.yml). Allows linking services.
Volume Persist data outside of container’s filesystem. Example:
docker volume create data_vol
docker run -v data_vol:/data myapp:1.0
Network Custom networks let containers talk to each other by name.
Example:
docker network create mynet
docker run --network=mynet --name=db ...
Best Practices - Use small base images (e.g., Alpine) for minimal footprint.
- Leverage multi-stage builds for lighter final images.
- Keep container processes short-lived (one main process if possible).
- Utilize .dockerignore to reduce build context size.
- Set explicit versions for dependencies.
- Use caching effectively (order instructions from least-changing to most-changing).
- Run as non-root if possible (USER directive).

Here is an example of a Dockerfile built following best practices. You can copy it and use it to build any Dockerfile you need.


          # syntax=docker/dockerfile:1.5
          # This tells Docker which set of instructions (version 1.5) to use.
          # Think of it as choosing the rules for our recipe.

          # Use an ARG (argument) for the base image tag.
          # This means you can change the Node.js version when you build the image.
          ARG BASE_IMAGE_TAG=16-alpine
          # "16-alpine" means we're using Node.js version 16 on a lightweight Alpine Linux system.

          # Start with a Node.js image based on the tag above.
          FROM node:${BASE_IMAGE_TAG}
          # "FROM" tells Docker to begin with this pre-built Node.js image.
          # It’s like starting with a ready-made box that already has Node.js installed.

          # Add labels to the image for metadata.
          # Labels act like stickers that show who made the image and what it’s for.
          LABEL maintainer="your_email@example.com"
          LABEL description="Example Node.js application container."

          # (Tip: Use a .dockerignore file to exclude unnecessary files and speed up the build.)

          # Update package lists and install extra tools needed for building your app.
          RUN apk update && apk add --no-cache \
            python3 \   # Installs Python 3, which may be needed for building some packages.
            make \      # Installs 'make', a tool used to compile programs.
            g++ \       # Installs the GNU C++ compiler for compiling native add-ons.
            git         # Installs Git to help fetch code from repositories.
          # 'apk' is the package manager for Alpine Linux.

          # Create a new user and group to run the application safely.
          RUN addgroup -S appgroup && adduser -S appuser -G appgroup
          # 'addgroup -S' creates a system group named "appgroup".
          # 'adduser -S' creates a system user named "appuser" and adds it to "appgroup".
          USER appuser
          # Running as a non-root user improves security.

          # Set the working directory inside the container.
          WORKDIR /app
          # This is like saying, "let's work inside the /app folder from now on."

          # Copy package files first to take advantage of caching.
          COPY package*.json ./
          # Only the package.json files are copied first.
          # This helps Docker reuse this step later if these files haven't changed, making builds faster.

          # Install Node.js dependencies.
          RUN npm install --no-optional
          # 'npm install' downloads and installs the libraries your app needs.
          # The '--no-optional' flag skips extra packages that are not required.

          # Copy the rest of the application code into the container.
          COPY . /app
          # This brings all your project files into the /app folder inside the container.

          # (Optional) If your project needs to be built (like compiling code), you can add a build step here.
          # For example: RUN npm run build

          # Expose the port that your application will use.
          EXPOSE 3000
          # This tells Docker (and people reading the file) that your app listens on port 3000.
          # Note: This does not publish the port; it's for documentation and linking.

          # Define what happens when the container starts:
          # ENTRYPOINT:
          #   - This sets the main command that will always run when the container starts.
          #   - It cannot be easily overridden by additional arguments unless you use the --entrypoint flag.
          # CMD:
          #   - This provides default arguments for the ENTRYPOINT command.
          #   - If no arguments are passed when starting the container, CMD's values will be used.
          #   - However, if you pass arguments via the docker run command, those arguments override CMD,
          #     but the ENTRYPOINT remains in place.
          # In this example:
          #   ENTRYPOINT ["node"] tells Docker to always run the Node.js executable.
          #   CMD ["index.js"] provides the default file to run.
          # So, by default, the container will execute "node index.js".
          # If you run the container with extra arguments (e.g., docker run  server.js),
          # the command will become "node server.js", overriding the CMD value.
          ENTRYPOINT ["node"]
          CMD ["index.js"]